package com.foldingleaf.web.controller.order;


import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

import com.foldingleaf.collections.service.ISysCollectionService;
import com.foldingleaf.common.annotation.Log;
import com.foldingleaf.common.core.controller.BaseController;
import com.foldingleaf.common.core.domain.Result;
import com.foldingleaf.common.core.domain.entity.SysUser;
import com.foldingleaf.common.core.page.TableDataInfo;
import com.foldingleaf.common.core.redis.RedisCache;
import com.foldingleaf.common.enums.BusinessType;
import com.foldingleaf.common.utils.poi.ExcelUtil;
import com.foldingleaf.common.utils.uuid.UUID;
import com.foldingleaf.framework.web.service.UserDetailsServiceImpl;
import com.foldingleaf.order.domain.SysCollectionOrder;
import com.foldingleaf.order.service.ISysCollectionOrderService;

import com.foldingleaf.recharge.domain.AlipayRechargeOrder;
import com.foldingleaf.recharge.service.IAlipayRechargeOrderService;
import com.foldingleaf.record.domain.SysCollectionOrderRecord;
import com.foldingleaf.record.service.ISysCollectionOrderRecordService;
import com.foldingleaf.show.domain.SysCollection;
import com.foldingleaf.show.domain.SysCollectionShow;
import com.foldingleaf.show.service.ISysCollectionShowService;
import com.foldingleaf.system.service.ISysUserService;
import com.foldingleaf.web.controller.order.pay.*;

import com.foldingleaf.web.controller.order.utlis.RedisLock;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import io.swagger.annotations.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.security.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 藏品订单Controller
 * 
 * @author ajian
 * @date 2022-06-02
 */
@Api(value = "/order/order", tags = {"藏品订单Controller"})
@RestController
@RequestMapping("/order/order")
public class SysCollectionOrderController extends BaseController
{

    private static final org.slf4j.Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class);
    @Autowired
    private RedisLock redisLock;
    @Autowired
    private ISysCollectionOrderService sysCollectionOrderService;
    @Autowired
    private ISysCollectionService sysCollectionService;
    @Autowired

    private ISysCollectionShowService sysCollectionShowService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private YmlParament ymlParament;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ISysCollectionOrderRecordService sysCollectionOrderRecordService;
    @Autowired
    private IAlipayRechargeOrderService alipayRechargeOrderService;
    /**
     * 查询藏品订单列表
     */

    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "SysCollectionOrder", name = "sysCollectionOrder", value = "")
    })
    @ApiOperation(value = "查询藏品订单列表", notes = "查询藏品订单列表", httpMethod = "GET")

    @GetMapping("/list")
    public TableDataInfo list(SysCollectionOrder sysCollectionOrder)
    {
        startPage();
        List<SysCollectionOrder> list = sysCollectionOrderService.selectSysCollectionOrderList(sysCollectionOrder);
        return getDataTable(list);
    }

    /**
     * 导出藏品订单列表
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "HttpServletResponse", name = "response", value = ""),
            @ApiImplicitParam(paramType = "query", dataType = "SysCollectionOrder", name = "sysCollectionOrder", value = "")
    })
    @ApiOperation(value = "导出藏品订单列表", notes = "导出藏品订单列表", httpMethod = "POST")
    @PreAuthorize("@ss.hasPermi('order:order:export')")
    @Log(title = "藏品订单", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, SysCollectionOrder sysCollectionOrder)
    {
        List<SysCollectionOrder> list = sysCollectionOrderService.selectSysCollectionOrderList(sysCollectionOrder);
        ExcelUtil<SysCollectionOrder> util = new ExcelUtil<SysCollectionOrder>(SysCollectionOrder.class);
        util.exportExcel(response, list, "藏品订单数据");
    }

    /**
     * 获取藏品订单详细信息
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", dataType = "long", name = "collectionOrderId", value = "")
    })
    @ApiOperation(value = "获取藏品订单详细信息", notes = "获取藏品订单详细信息", httpMethod = "GET")
    @PreAuthorize("@ss.hasPermi('order:order:query')")
    @GetMapping(value = "/{collectionOrderId}")
    public Result getInfo(@PathVariable("collectionOrderId") Long collectionOrderId)
    {
        return Result.success(sysCollectionOrderService.selectSysCollectionOrderByCollectionOrderId(collectionOrderId));
    }


    /**
     * 邀请用户免费领取
     */

    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "long", name = "collectionShowID", value = ""),
            @ApiImplicitParam(paramType = "query", dataType = "long", name = "userId", value = "")
    })
    @ApiOperation(value = "邀请用户免费领取", notes = "邀请用户免费领取", httpMethod = "POST")
    @PostMapping(value = "/inviteUserFree")
    @Transactional
    public Result inviteUserFreeCollection(Long collectionShowID, Long userId){


        try {

            SysCollectionShow sysCollectionShow = sysCollectionShowService.selectSysCollectionShowByCollectionShowIdAndIsSell(collectionShowID);
            if (sysCollectionShow == null) {
                return Result.error("藏品不存在");
            }
            if (sysCollectionShow.getSysCollectionList().size() == 0) {
                return Result.error("藏品为空");
            }

            SysUser sysUser = sysUserService.selectUserById(userId);
            if(sysUser == null){
                return Result.error("用户不存在,请先登录");
            }
            if(sysUser.getRealName() == null || sysUser.getRealName().equals("")||sysUser.getIdCard() == null || sysUser.getIdCard().equals("")){
                return Result.error("请先完善个人实名信息");
            }
            SysUser sysUser1 = new SysUser();
            sysUser1.setInviteCodeByUserId(sysUser.getInviteCode());
            List<SysUser> sysUsers = sysUserService.selectUserList(sysUser1);
            if(sysUsers.size() == 0){
                return Result.error("你还没有邀请新用户注册并实名");
            }
            if (new Date().getTime() < sysCollectionShow.getCollectionTime()) {
                return Result.error("藏品还未开放领取");
            }
            //获取sysUsers中realName并且idcard的不为空和空字符串的数量
            int realCount = 0;

            for(SysUser user : sysUsers){
                if(user.getRealName() != null && !user.getRealName().equals("")&&user.getIdCard() != null && !user.getIdCard().equals("")){
                    realCount++;
                }

            }


            SysCollectionOrder sysCollectionOrder = new SysCollectionOrder();
            sysCollectionOrder.setUserId(userId);
            List<SysCollectionOrder> sysCollectionOrderss = sysCollectionOrderService.selectSysCollectionOrderList(sysCollectionOrder);
            //获取sysCollectionOrders数组中的orderStatus=4的数量
            int count = 0;
            for(SysCollectionOrder sysCollectionOrder1 : sysCollectionOrderss){
                if(Objects.equals(sysCollectionOrder1.getOrderStatus(), "4")){
                    count++;
                }
            }
            if(realCount/4 <= count){
                return Result.error("每邀请4个用户并且实名认证,即可获取一次领取藏品的资格");
            }
            sysCollectionOrder.setCollectionShowId(129L);
            List<SysCollectionOrder> sysCollectionOrders1 = sysCollectionOrderService.selectSysCollectionOrderList(sysCollectionOrder);
            if (sysCollectionOrders1.size()>50) {
                return Result.error("藏品限量赠送50份");
            }

            SysCollection sysCollection = sysCollectionShow.getSysCollectionList().get(0);
            sysCollection.setIsSell("1");
            sysCollectionOrder.setCollectionId(sysCollection.getCollectionId());
            sysCollectionOrder.setCollectionName(sysCollection.getCollectionName());
            sysCollectionOrder.setCollectionPrice(sysCollection.getCollectionPrice());
            sysCollectionOrder.setOrderPrice(sysCollection.getCollectionPrice());
            sysCollectionOrder.setCreateTime(new Date());
            sysCollectionOrder.setCollectionHashId(sysCollection.getCollectionHashId());
            sysCollectionOrder.setCollectionShowId(sysCollection.getCollectionShowId());
            sysCollectionOrder.setCollectionUrl(sysCollection.getCollectionUrl());
            sysCollectionOrder.setCollectionAuthorId(sysCollection.getCollectionAuthorId());
            sysCollectionOrder.setCollectionDesc(sysCollection.getCollectionDesc());
            //获取当前时间 yyyy-MM-dd HH:mm:ss格式
            sysCollectionOrder.setExpireTime(new Date().getTime() + (1000 * 60 * 5));
            //4 免费领取 订单  5 第一次认证订单
            sysCollectionOrder.setOrderStatus("4");
            //生成订单编号 年月日时分秒+随机数 例如：2018070810101010101 共20位 前面10位为时间，后面10位为随机数
            String orderId = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + (int) (Math.random() * 100000000);
            sysCollectionOrder.setCollectionOrderNo(orderId);
            String s = UUID.randomUUID().toString(true);
            sysCollectionOrder.setCollectionOrderNoHashId("0x"+s);
            sysCollectionOrder.setUserId(userId);
            sysCollectionOrder.setFinishTime(new Date().getTime());
            sysCollectionService.updateSysCollection(sysCollection);
            sysCollectionOrderService.insertSysCollectionOrder(sysCollectionOrder);
            SysCollectionOrder sysCollectionOrdere = new SysCollectionOrder();
            sysCollectionOrdere.setCollectionOrderNo(orderId);
            //查询订单 修改订单状态



            List<SysCollectionOrder> sysCollectionOrders = sysCollectionOrderService.selectSysCollectionOrderList(sysCollectionOrdere);
            SysCollectionOrder collectionOrder = sysCollectionOrders.get(0);

            SysCollectionOrderRecord sysCollectionOrderRecord = new SysCollectionOrderRecord();
            sysCollectionOrderRecord.setCollectionOrderNo(orderId);
            sysCollectionOrderRecord.setCollectionOrderId(collectionOrder.getCollectionOrderId());
            sysCollectionOrderRecord.setCollectionDesc(collectionOrder.getCollectionDesc());
            sysCollectionOrderRecord.setCollectionAuthorId(collectionOrder.getCollectionAuthorId());
            sysCollectionOrderRecord.setCollectionUrl(collectionOrder.getCollectionUrl());
            sysCollectionOrderRecord.setCollectionPrice(collectionOrder.getCollectionPrice());
            sysCollectionOrderRecord.setCollectionOrderNoHashId(collectionOrder.getCollectionOrderNoHashId());
            sysCollectionOrderRecord.setCollectionHashId(collectionOrder.getCollectionHashId());
            sysCollectionOrderRecord.setCollectionName(collectionOrder.getCollectionName());
            sysCollectionOrderRecord.setCollectionId(collectionOrder.getCollectionId());
            sysCollectionOrderRecord.setFinishTime(collectionOrder.getFinishTime());
            sysCollectionOrderRecord.setOldUserId(sysCollection.getUserId());
            sysCollectionOrderRecord.setCreateTime(collectionOrder.getCreateTime());
            SysUser sysUser3 = sysUserService.selectUserById(sysCollection.getUserId());
            sysCollectionOrderRecord.setOldUserHashId(sysUser3.getHashId());
            sysCollectionOrderRecord.setUserId(collectionOrder.getUserId());
            SysUser sysUser2 = sysUserService.selectUserById(collectionOrder.getUserId());
            sysCollectionOrderRecord.setUserHashId(sysUser2.getHashId());
            sysCollectionOrderRecord.setOrderPrice(collectionOrder.getOrderPrice());

            sysCollectionOrderRecordService.insertSysCollectionOrderRecord(sysCollectionOrderRecord);
            //修改订单用户
            sysCollection.setUserId(sysCollectionOrder.getUserId());
            //添加id
            sysCollection.setCollectionOrderNoHashId(sysCollectionOrder.getCollectionOrderNoHashId());
            //添加时间
            sysCollection.setColletionTime(new Date().getTime());
            //修改详情表
            sysCollectionService.updateSysCollection(sysCollection);




        }catch (Exception e){
            e.printStackTrace();
            return Result.error("领取失败");
        }



        return  success();
    }


    /**
     * 邀请记录
     *
     * @param userId
     *
     * @return*/
    @RequestMapping("/inviteRecord")
    public TableDataInfo inviteRecord(@RequestParam("userId") Long userId) {

        startPage();
        try {
            Result result = new Result();
            SysUser sysUser = sysUserService.selectUserById(userId);

            SysUser  sysUser2 = new SysUser();
            sysUser2.setInviteCodeByUserId(sysUser.getInviteCode());
            ArrayList<SysUser> sysUsers = new ArrayList<>();
            for (SysUser user : sysUserService.selectUserList(sysUser2)) {
                SysUser sysUser1 = new SysUser();

                sysUser1.setNickName(user.getNickName());
                sysUser1.setHashId(user.getHashId());
                sysUser1.setAvatar(user.getAvatar());
                sysUser1.setCreateTime(user.getCreateTime());
                if (user.getRealName() != null&&!user.getRealName().equals("")){
                    sysUser1.setRealName(user.getRealName().charAt(0)+"**");
                }

                sysUsers.add(sysUser1);

            }
            Collections.reverse(sysUsers);
         result.put("rows", sysUsers);
            return  getDataTable(sysUsers);
        } catch (Exception e) {
            log.error("邀请记录获取失败", e);
        }

        return getDataTable(new ArrayList<>());
    }
    /**
     * 赠送藏品
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "long", name = "userId", value = ""),
            @ApiImplicitParam(paramType = "query", dataType = "long", name = "collectionId", value = ""),
            @ApiImplicitParam(paramType = "query", dataType = "string", name = "userHashId", value = "")
    })
    @ApiOperation(value = "赠送藏品", notes = "赠送藏品", httpMethod = "POST")
    @PostMapping("/giveCollection")
    @Transactional
   public Result  giveCollection(Long userId,Long collectionId,String userHashId){


          try {


              SysCollection sysCollection = sysCollectionService.selectSysCollectionByCollectionId(collectionId);
              if (!Objects.equals(sysCollection.getUserId(), userId)){
                  return Result.error("该藏品不属于你");
              }
              SysUser sysUser =new SysUser();
              sysUser.setHashId(userHashId);
              List<SysUser> sysUsers = sysUserService.selectUserList(sysUser);
              if(sysUsers.size() == 0){
                  return Result.error("赠送的用户不存在,请检查输入的链上Id");
              }
              SysUser sysUser1 = sysUsers.get(0);
              if(Objects.equals(sysUser1.getUserId(),userId)){
                  return Result.error("不能赠送给自己");
              }
              long time = new Date().getTime();
              if (new Date().getTime()<  sysCollection.getColletionTime()+(60*60*24*1000*2)&&sysCollection.getUserId()!=113&&sysCollection.getUserId()!=157&&sysCollection.getUserId()!=111&&sysCollection.getUserId()!=100){
                  //计算当前时间和sysCollection.getColletionTime()*259200000相差几天
                  SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss" );
                  return Result.error("您在"+format.format(new Date(sysCollection.getColletionTime()+(60*60*24*1000*2)))+"后即可转赠,需要最少持有两天才可以赠送");
              }
              SysCollectionOrder sysCollectionOrder = new SysCollectionOrder();
              sysCollectionOrder.setCreateTime(new Date());

              sysCollectionOrder.setCollectionId(sysCollection.getCollectionId());
              sysCollectionOrder.setCollectionName(sysCollection.getCollectionName());
              sysCollectionOrder.setCollectionPrice(sysCollection.getCollectionPrice());
              sysCollectionOrder.setOrderPrice(sysCollection.getCollectionPrice());
              sysCollectionOrder.setCollectionHashId(sysCollection.getCollectionHashId());
              sysCollectionOrder.setCollectionShowId(sysCollection.getCollectionShowId());
              sysCollectionOrder.setCollectionUrl(sysCollection.getCollectionUrl());
              sysCollectionOrder.setCollectionAuthorId(sysCollection.getCollectionAuthorId());
              sysCollectionOrder.setCollectionDesc(sysCollection.getCollectionDesc());
              //获取当前时间 yyyy-MM-dd HH:mm:ss格式

              sysCollectionOrder.setExpireTime(new Date().getTime() + (1000 * 60 * 5));
              //4 免费领取 订单  5 第一次认证订单 6 赠送订单
              sysCollectionOrder.setOrderStatus("6");
              //生成订单编号 年月日时分秒+随机数 例如：2018070810101010101 共20位 前面10位为时间，后面10位为随机数
              String orderId = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + (int) (Math.random() * 100000000);
              sysCollectionOrder.setCollectionOrderNo(orderId);
              String s = UUID.randomUUID().toString(true);
              sysCollectionOrder.setCollectionOrderNoHashId("0x"+s);


              sysCollectionOrder.setUserId(sysUser1.getUserId());
              //插入订单
              sysCollectionOrder.setFinishTime(new Date().getTime());
              sysCollectionService.updateSysCollection(sysCollection);

              sysCollectionOrderService.insertSysCollectionOrder(sysCollectionOrder);



              SysCollectionOrder sysCollectionOrdere = new SysCollectionOrder();
              sysCollectionOrdere.setCollectionOrderNo(orderId);
              //查询订单 修改订单状态



              List<SysCollectionOrder> sysCollectionOrders = sysCollectionOrderService.selectSysCollectionOrderList(sysCollectionOrdere);
              SysCollectionOrder collectionOrder = sysCollectionOrders.get(0);

              SysCollectionOrderRecord sysCollectionOrderRecord = new SysCollectionOrderRecord();
              sysCollectionOrderRecord.setCollectionOrderNo(orderId);
              sysCollectionOrderRecord.setCollectionOrderId(collectionOrder.getCollectionOrderId());
              sysCollectionOrderRecord.setCollectionDesc(collectionOrder.getCollectionDesc());
              sysCollectionOrderRecord.setCollectionAuthorId(collectionOrder.getCollectionAuthorId());
              sysCollectionOrderRecord.setCollectionUrl(collectionOrder.getCollectionUrl());
              sysCollectionOrderRecord.setCollectionPrice(collectionOrder.getCollectionPrice());
              sysCollectionOrderRecord.setCollectionOrderNoHashId(collectionOrder.getCollectionOrderNoHashId());
              sysCollectionOrderRecord.setCollectionHashId(collectionOrder.getCollectionHashId());
              sysCollectionOrderRecord.setCollectionName(collectionOrder.getCollectionName());
              sysCollectionOrderRecord.setCollectionId(collectionOrder.getCollectionId());
              sysCollectionOrderRecord.setFinishTime(collectionOrder.getFinishTime());
              sysCollectionOrderRecord.setOldUserId(sysCollection.getUserId());
              sysCollectionOrderRecord.setCreateTime(collectionOrder.getCreateTime());
              SysUser sysUser3 = sysUserService.selectUserById(sysCollection.getUserId());
              sysCollectionOrderRecord.setOldUserHashId(sysUser3.getHashId());
              sysCollectionOrderRecord.setUserId(collectionOrder.getUserId());
              SysUser sysUser2 = sysUserService.selectUserById(collectionOrder.getUserId());
              sysCollectionOrderRecord.setUserHashId(sysUser2.getHashId());
              sysCollectionOrderRecord.setOrderPrice(collectionOrder.getOrderPrice());

              sysCollectionOrderRecordService.insertSysCollectionOrderRecord(sysCollectionOrderRecord);
              //修改订单用户
              sysCollection.setUserId(sysCollectionOrder.getUserId());
              //添加id
              sysCollection.setCollectionOrderNoHashId(sysCollectionOrder.getCollectionOrderNoHashId());
              //添加时间
              sysCollection.setColletionTime(new Date().getTime());
              //修改详情表
              sysCollectionService.updateSysCollection(sysCollection);
          }catch (Exception e){
                e.printStackTrace();
                return Result.error("赠送失败");
          }


       return  Result.success("赠送成功");
   }



    /**
     * 免费藏品领取
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "long", name = "collectionShowID", value = ""),
            @ApiImplicitParam(paramType = "query", dataType = "long", name = "userId", value = "")
    })
    @ApiOperation(value = "免费藏品领取", notes = "免费藏品领取", httpMethod = "POST")
    @PostMapping("/free")
    @Transactional
    public Result freeCollection(Long collectionShowID, Long userId) {

               try {
                   SysCollectionShow sysCollectionShow = sysCollectionShowService.selectSysCollectionShowByCollectionShowIdAndIsSell(collectionShowID);
                   if (sysCollectionShow == null) {
                       return Result.error("藏品不存在");
                   }
                   if (sysCollectionShow.getSysCollectionList().size() == 0) {
                       return Result.error("藏品为空");
                   }
                   SysUser sysUser = sysUserService.selectUserById(userId);
                   if(sysUser.getRealName() == null || sysUser.getRealName().equals("")||sysUser.getIdCard() == null || sysUser.getIdCard().equals("")){
                       return Result.error("请先完善个人实名信息");
                   }
                   if (sysUser.getIsBindReal().equals("1")&&userId!=100L) {
                       return Result.error("您已经领取过藏品了,请勿重复领取");
                   }
                   if (sysUser == null) {
                       return Result.error(401,"用户不存在，请先登录");
                   }
                   if (new Date().getTime()<sysCollectionShow.getCollectionTime()) {
                          return Result.error("藏品还未开放领取");
                   }

                   if (sysUser.getInviteCodeByUserId() == null) {
                       return Result.error("很抱歉，您不是被邀请的新用户，详情请查看邀请活动");
                   }
                   SysUser sysUser1 = new SysUser();
                   sysUser1.setInviteCode(sysUser.getInviteCodeByUserId());
                   List<SysUser> sysUsers = sysUserService.selectUserList(sysUser1);
                   if (sysUsers.size() == 0) {
                       return Result.error("很抱歉，您的邀请人不存在，如有错误，请反馈");
                   }
                   SysCollectionOrder sysCollectionOrder = new SysCollectionOrder();
                   SysCollection sysCollection = sysCollectionShow.getSysCollectionList().stream().filter(x -> x.getIsSell().equals("0")).findFirst().orElseThrow(() -> new BusinessException("该藏品已售空"));
                   sysCollection.setIsSell("1");
                   sysCollectionOrder.setCreateTime(new Date());

                   sysCollectionOrder.setCollectionId(sysCollection.getCollectionId());
                   sysCollectionOrder.setCollectionName(sysCollection.getCollectionName());
                   sysCollectionOrder.setCollectionPrice(sysCollection.getCollectionPrice());
                   sysCollectionOrder.setOrderPrice(sysCollection.getCollectionPrice());
                   sysCollectionOrder.setCollectionHashId(sysCollection.getCollectionHashId());
                   sysCollectionOrder.setCollectionShowId(sysCollection.getCollectionShowId());
                   sysCollectionOrder.setCollectionUrl(sysCollection.getCollectionUrl());
                   sysCollectionOrder.setCollectionAuthorId(sysCollection.getCollectionAuthorId());
                   sysCollectionOrder.setCollectionDesc(sysCollection.getCollectionDesc());
                   //获取当前时间 yyyy-MM-dd HH:mm:ss格式

                   sysCollectionOrder.setExpireTime(new Date().getTime() + (1000 * 60 * 5));
                   //4 免费领取 订单  5 第一次认证订单
                   sysCollectionOrder.setOrderStatus("5");
                   //生成订单编号 年月日时分秒+随机数 例如：2018070810101010101 共20位 前面10位为时间，后面10位为随机数
                   String orderId = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + (int) (Math.random() * 100000000);
                   sysCollectionOrder.setCollectionOrderNo(orderId);
                   String s = UUID.randomUUID().toString(true);
                   sysCollectionOrder.setCollectionOrderNoHashId("0x"+s);


                   sysCollectionOrder.setUserId(userId);
                   //插入订单
                   sysCollectionOrder.setFinishTime(new Date().getTime());
                   sysCollectionService.updateSysCollection(sysCollection);

                   sysCollectionOrderService.insertSysCollectionOrder(sysCollectionOrder);



                   SysCollectionOrder sysCollectionOrdere = new SysCollectionOrder();
                   sysCollectionOrdere.setCollectionOrderNo(orderId);
                   //查询订单 修改订单状态



                   List<SysCollectionOrder> sysCollectionOrders = sysCollectionOrderService.selectSysCollectionOrderList(sysCollectionOrdere);
                   SysCollectionOrder collectionOrder = sysCollectionOrders.get(0);

                   SysCollectionOrderRecord sysCollectionOrderRecord = new SysCollectionOrderRecord();
                   sysCollectionOrderRecord.setCollectionOrderNo(orderId);
                   sysCollectionOrderRecord.setCollectionOrderId(collectionOrder.getCollectionOrderId());
                   sysCollectionOrderRecord.setCollectionDesc(collectionOrder.getCollectionDesc());
                   sysCollectionOrderRecord.setCollectionAuthorId(collectionOrder.getCollectionAuthorId());
                   sysCollectionOrderRecord.setCollectionUrl(collectionOrder.getCollectionUrl());
                   sysCollectionOrderRecord.setCollectionPrice(collectionOrder.getCollectionPrice());
                   sysCollectionOrderRecord.setCollectionOrderNoHashId(collectionOrder.getCollectionOrderNoHashId());
                   sysCollectionOrderRecord.setCollectionHashId(collectionOrder.getCollectionHashId());
                   sysCollectionOrderRecord.setCollectionName(collectionOrder.getCollectionName());
                   sysCollectionOrderRecord.setCollectionId(collectionOrder.getCollectionId());
                   sysCollectionOrderRecord.setFinishTime(collectionOrder.getFinishTime());
                   sysCollectionOrderRecord.setOldUserId(sysCollection.getUserId());
                   sysCollectionOrderRecord.setCreateTime(collectionOrder.getCreateTime());
                   SysUser sysUser3 = sysUserService.selectUserById(sysCollection.getUserId());
                   sysCollectionOrderRecord.setOldUserHashId(sysUser3.getHashId());
                   sysCollectionOrderRecord.setUserId(collectionOrder.getUserId());
                   SysUser sysUser2 = sysUserService.selectUserById(collectionOrder.getUserId());
                   sysCollectionOrderRecord.setUserHashId(sysUser2.getHashId());
                   sysCollectionOrderRecord.setOrderPrice(collectionOrder.getOrderPrice());

                   sysCollectionOrderRecordService.insertSysCollectionOrderRecord(sysCollectionOrderRecord);
                   //修改订单用户
                   sysCollection.setUserId(sysCollectionOrder.getUserId());
                   //添加id
                   sysCollection.setCollectionOrderNoHashId(sysCollectionOrder.getCollectionOrderNoHashId());
                   //添加时间
                   sysCollection.setColletionTime(new Date().getTime());
                   //修改详情表
                   sysCollectionService.updateSysCollection(sysCollection);
                   sysUser.setIsBindReal("1");
                   sysUserService.updateUser(sysUser);
               }catch (Exception e){
                     e.printStackTrace();
                     return Result.error("领取失败");
               }

        return  Result.success();
    }


    /**
     * 订单付款
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", dataType = "long", name = "collectionOrderId", value = ""),
            @ApiImplicitParam(paramType = "query", dataType = "int", name = "payType", value = "")
    })
    @ApiOperation(value = "订单付款", notes = "订单付款", httpMethod = "POST")
    @PostMapping("/pay")
    public Result pay(Long collectionOrderId,Integer payType) throws AlipayApiException {

        SysCollectionOrder sysCollectionOrder = sysCollectionOrderService.selectSysCollectionOrderByCollectionOrderId(collectionOrderId);

        if (sysCollectionOrder.getExpireTime() < new Date().getTime()){
            return Result.error("订单已过期");
        }
        if (payType == 2) {
            //支付宝支付

            AlipayConfig alipayConfig = new AlipayConfig();
            AlipayClient alipayClient = alipayConfig.setAlipayClient();

            AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();

            AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
            model.setOutTradeNo(sysCollectionOrder.getCollectionOrderNo());
            //sysCollectionOrder.getOrderPrice()转换为double
            model.setTotalAmount(String.valueOf(sysCollectionOrder.getOrderPrice().doubleValue()));



            model.setSubject(sysCollectionOrder.getCollectionName());

//
//            List<GoodsDetail> goodsDetail = new ArrayList<GoodsDetail>();
//            GoodsDetail goodsDetail0 = new GoodsDetail();
//
//            goodsDetail0.setGoodsName(sysCollectionOrder.getCollectionName());
//            goodsDetail0.setQuantity(1L);
//            goodsDetail0.setPrice(String.valueOf(sysCollectionOrder.getOrderPrice()));
//            goodsDetail.add(goodsDetail0);
//            model.setGoodsDetail(goodsDetail);
            request.setNotifyUrl("https://collector.zdsenlin.com/order/order/alinotify");
            request.setBizModel(model);
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            if (response.isSuccess()) {
                //调用成功

                SysUser sysUser = sysUserService.selectUserById(sysCollectionOrder.getUserId());
                sysUser.setPriorityPurchaseId(sysUser.getPriorityPurchaseId()-1);
                sysUserService.updateUser(sysUser);
                return    Result.success(response.getBody());
            }else {
                return    Result.error("支付宝支付失败");
            }
        }else if (payType == 1) {
            //微信支付
            System.out.println("微信支付");

            try {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ObjectMapper objectMapper = new ObjectMapper();

                ObjectNode rootNode = objectMapper.createObjectNode();
                rootNode.put("mchid","1605365324")
                        .put("appid", "wx7cbb0097ff50e3e3")
                        .put("description", sysCollectionOrder.getCollectionName())
                        .put("notify_url", "https://collector.zdsenlin.com/order/order/wxAppPayNotify/")
                        .put("out_trade_no", sysCollectionOrder.getCollectionOrderNo());
                rootNode.putObject("amount")
                        //double转换为int

                        .put("total", (int) (sysCollectionOrder.getOrderPrice().doubleValue() * 100)).put("currency", "CNY");
                log.info("微信支付参数："+rootNode.toString());

                objectMapper.writeValue(bos, rootNode);

                String prepayId = V3PayPost("https://api.mch.weixin.qq.com/v3/pay/transactions/app", objectMapper.writeValueAsString(rootNode));
                logger.info("prepayId:"+prepayId);
                JSONObject result = WxAppPayTuneUp(prepayId, "wx7cbb0097ff50e3e3", "1605365324", "cert/apiclient_key.pem",false);
                if (result!=null&&result.get("appId").equals("wx7cbb0097ff50e3e3")) {
                    SysUser sysUser = sysUserService.selectUserById(sysCollectionOrder.getUserId());
                    sysUser.setPriorityPurchaseId(sysUser.getPriorityPurchaseId()-1);
                    sysUserService.updateUser(sysUser);
                    return  Result.success(result);
                }else {
                    return  Result.error("微信调用支付失败");
                }

            }catch ( Exception e){
                return  Result.error("微信调用支付失败");
            }

        }
        return success();
    }

    /**
     * alipay
     */
    @PostMapping("/alipay")
    public Result alipay(Integer rechargeType,String phone,Integer num,Integer payType,String openId) throws AlipayApiException {

        SysUser sysUser = sysUserService.selectUserByUserName(phone);

        if (sysUser==null){
            return Result.error("获取用户信息异常");
        }
        String orderId = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + (int) (Math.random() * 100000000);


        //------------------------------------------------------
        AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
        model.setOutTradeNo(orderId);
        //sysCollectionOrder.getOrderPrice()转换为double
        if (rechargeType==1){
            model.setTotalAmount("20.00");
            model.setSubject("20树叶");
        }else if (rechargeType==2){
            model.setTotalAmount("30.00");
            model.setSubject("30树叶");
        }else if (rechargeType==3){
            model.setTotalAmount("40.00");
            model.setSubject("40树叶");
        }else if (rechargeType==4){
            model.setTotalAmount("70.00");
            model.setSubject("70树叶");
        }else if (rechargeType==5){
            model.setTotalAmount("110.00");
            model.setSubject("110树叶");

        }else if (rechargeType==6){
            model.setTotalAmount("245.00");
            model.setSubject("245树叶");
        }else  if (rechargeType==7){
            model.setTotalAmount(String.valueOf(num));
            model.setSubject(num+"树叶");
        }else {
            return Result.error("充值类型错误");
        }
        //------------------------------------------------------
        if (payType==0){
            AlipayConfig alipayConfig = new AlipayConfig();
            AlipayClient alipayClient = alipayConfig.setAlipayClient();

            AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();

            AlipayRechargeOrder alipayRechargeOrder = new AlipayRechargeOrder();
            alipayRechargeOrder.setOrderNo(orderId);
            alipayRechargeOrder.setUserId(sysUser.getUserId());
            alipayRechargeOrder.setPayType("1");
            alipayRechargeOrder.setAmount(new BigDecimal(model.getTotalAmount()));
            alipayRechargeOrder.setStatus("0");
            alipayRechargeOrderService.insertAlipayRechargeOrder(alipayRechargeOrder);

            request.setNotifyUrl("https://collector.zdsenlin.com/order/order/alinotify/racharge");
            request.setBizModel(model);
            String response = alipayClient.pageExecute(request).getBody();


            System.out.println(response);
            return Result.success(response);
        }else if(payType==1) {
            AlipayRechargeOrder alipayRechargeOrder = new AlipayRechargeOrder();
            alipayRechargeOrder.setOrderNo(orderId);
            alipayRechargeOrder.setUserId(sysUser.getUserId());
            alipayRechargeOrder.setPayType("1");
            alipayRechargeOrder.setAmount(new BigDecimal(model.getTotalAmount()));
            alipayRechargeOrder.setStatus("0");
            //getTotalAmount()转换为double

            alipayRechargeOrderService.insertAlipayRechargeOrder(alipayRechargeOrder);
            String url = "https://pay.senhuo.cn/pay/Pay.php?out_trade_no="+orderId+"&appid=zp1655616322&sub_notify_url=https://collector.zdsenlin.com/order/order/othernotify&total="+ Double.parseDouble(model.getTotalAmount())*100+"&title="+model.getSubject()+"&redirect_url=https://collector.zdsenlin.com/loginwx.html";
            return Result.success(url);
        }else if (payType==2){


            try {
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ObjectMapper objectMapper = new ObjectMapper();

                ObjectNode rootNode = objectMapper.createObjectNode();
                rootNode.put("mchid","1605365324")
                        .put("appid", "wx61f4fbd46508977d")
                        .put("description", model.getSubject())
                        .put("notify_url", "https://collector.zdsenlin.com/order/order/wxAppPayNotify/")
                        .put("out_trade_no", orderId);
                rootNode.putObject("amount")
                        //double转换为int

                        .put("total", (int) (new  BigDecimal(model.getTotalAmount()).doubleValue()* 100)).put("currency", "CNY");
                rootNode.putObject("payer")
                                .put("openid",openId);
                log.info("微信支付参数："+rootNode.toString());

                objectMapper.writeValue(bos, rootNode);

                String prepayId = V3PayPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi", objectMapper.writeValueAsString(rootNode));
                logger.info("prepayId:"+prepayId);
                JSONObject result = WxAppPayTuneUp(prepayId, "wx61f4fbd46508977d", "1605365324", "cert/apiclient_key.pem",true);
                if (result.get("appId").equals("wx61f4fbd46508977d")) {

                    AlipayRechargeOrder alipayRechargeOrder = new AlipayRechargeOrder();
                    alipayRechargeOrder.setOrderNo(orderId);
                    alipayRechargeOrder.setUserId(sysUser.getUserId());
                    alipayRechargeOrder.setPayType("1");
                    alipayRechargeOrder.setAmount(new BigDecimal(model.getTotalAmount()));
                    alipayRechargeOrder.setStatus("0");
                    //getTotalAmount()转换为double

                    alipayRechargeOrderService.insertAlipayRechargeOrder(alipayRechargeOrder);


                    return  Result.success(result);
                }else {
                    return  Result.error("微信调用支付失败");
                }

            }catch ( Exception e){
                return  Result.error("微信调用支付失败");
            }
        }
    return error("请检查手机号码");
    }


    /**
     * app微信支付
     */
    @PostMapping("/appWxPay")
    @Transactional
    public Result appWxPay(Long userId,Integer num)  {
        SysUser sysUser = sysUserService.selectUserById(userId);
        if (sysUser==null){
            return Result.error("获取用户信息异常");
        }
        String orderId = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + (int) (Math.random() * 100000000);
                   //微信支付
                   System.out.println("微信支付");

                   try {
                       ByteArrayOutputStream bos = new ByteArrayOutputStream();
                       ObjectMapper objectMapper = new ObjectMapper();

                       ObjectNode rootNode = objectMapper.createObjectNode();
                       rootNode.put("mchid","1605365324")
                               .put("appid", "wx7cbb0097ff50e3e3")
                               .put("description", num+"树叶")
                               .put("notify_url", "https://collector.zdsenlin.com/order/order/wxAppPayNotify/")
                               .put("out_trade_no", orderId);
                       rootNode.putObject("amount")
                               //double转换为int

                               .put("total", (int) (num.doubleValue() * 100)).put("currency", "CNY");
                       log.info("微信支付参数："+rootNode.toString());

                       objectMapper.writeValue(bos, rootNode);

                       String prepayId = V3PayPost("https://api.mch.weixin.qq.com/v3/pay/transactions/app", objectMapper.writeValueAsString(rootNode));
                       logger.info("prepayId:"+prepayId);
                       JSONObject result = WxAppPayTuneUp(prepayId, "wx7cbb0097ff50e3e3", "1605365324", "cert/apiclient_key.pem",false);
                       if (result.get("appId").equals("wx7cbb0097ff50e3e3")) {

                           AlipayRechargeOrder alipayRechargeOrder = new AlipayRechargeOrder();
                           alipayRechargeOrder.setOrderNo(orderId);
                           alipayRechargeOrder.setUserId(sysUser.getUserId());
                           alipayRechargeOrder.setPayType("1");
                           alipayRechargeOrder.setAmount(new BigDecimal(num));
                           alipayRechargeOrder.setStatus("0");
                           //getTotalAmount()转换为double

                           alipayRechargeOrderService.insertAlipayRechargeOrder(alipayRechargeOrder);


                           return  Result.success(result);
                       }else {
                           return  Result.error("微信调用支付失败");
                       }

                   }catch ( Exception e){
                       return  Result.error("微信调用支付失败");
                   }



    }

    /**
     * 统计拉新人数
     */

    @PostMapping("/countNewUser")
    public Result countNewUser(){
        SysUser sysUser =new SysUser();
        List<SysUser> sysUsers = sysUserService.selectUserList(sysUser);
        ArrayList<HashMap<Object, Object> > list = new ArrayList();
        for (SysUser sysUser1 : sysUsers) {
            SysCollection sysCollection = new SysCollection();
            sysCollection.setUserId(sysUser1.getUserId());
            List<SysCollection> sysCollections = sysCollectionService.selectSysCollectionList(sysCollection);
            if (sysCollections.size()>=4){
                HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
                objectObjectHashMap.put("userId",sysUser1.getUserId());
                objectObjectHashMap.put("size",sysCollections.size());
                //整除
                objectObjectHashMap.put("MaybeCount",sysCollections.size()/4);
                list.add(objectObjectHashMap);
            }
        }
        return Result.success(list);
    }
    /**
     * 阿里充值回调
     */
    @PostMapping("/alinotify/racharge")
    public String rachargeNotify(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException {
        Map<String, String> params = convertRequestParamsToMap(request); // 将异步通知中收到的待验证所有参数都存放到map中
        String paramsJson = JSON.toJSONString(params);
        log.info("支付宝回调，{}"+ paramsJson);
        try {
            AlipayConfig alipayConfig = new AlipayConfig();// 支付宝配置
            // 调用SDK验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(params, ymlParament.getAlipayPublickey(), ymlParament.getCharset(),
                    ymlParament.getSignType());
            if (signVerified) {
                log.info("支付宝回调签名认证成功");
                // 按照支付结果异步通知中的描述，对支付结果中的业务内容进行1\2\3\4二次校验，校验成功后在response中返回success，校验失败返回failure
                this.check(params);
                // 另起线程处理业务
                executorService.execute(new Runnable() {
                    @Override
                    public void run() {
                        AlipayNotifyParam param = buildAlipayNotifyParam(params);
                        String trade_status = param.getTradeStatus();
                        // 支付成功
                        if (trade_status.equals("TRADE_SUCCESS")
                                || trade_status.equals("TRADE_FINISHED")) {
                            // 处理支付成功逻辑
                            try {
                                System.out.println("======================l============================");
                                logger.info(params.get("out_trade_no"));

                                String outTradeNo = params.get("out_trade_no");
                                logger.info("out_trade_no，{}", outTradeNo);
                                // 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
                                AlipayRechargeOrder alipayRechargeOrder = new AlipayRechargeOrder();
                                alipayRechargeOrder.setOrderNo(outTradeNo);
                                List<AlipayRechargeOrder> alipayRechargeOrders = alipayRechargeOrderService.selectAlipayRechargeOrderList(alipayRechargeOrder);
                                if (alipayRechargeOrders.size()>0) {
                                    alipayRechargeOrder = alipayRechargeOrders.get(0);
                                    alipayRechargeOrder.setStatus("1");
                                    alipayRechargeOrder.setFinishTime(new Date());
                                    alipayRechargeOrderService.updateAlipayRechargeOrder(alipayRechargeOrder);

                                    SysUser sysUser = sysUserService.selectUserById(alipayRechargeOrder.getUserId());
                                    sysUser.setBalance(sysUser.getBalance().add(alipayRechargeOrder.getAmount()));
                                    sysUserService.updateUser(sysUser);

                                }
                            } catch (Exception e) {
                                logger.error("支付宝回调业务处理报错,params:" + paramsJson, e);
                            }
                        } else {
                            logger.error("没有处理支付宝回调业务，支付宝交易状态：{},params:{}",trade_status,paramsJson);
                        }
                    }
                });
                // 如果签名验证正确，立即返回success，后续业务另起线程单独处理
                // 业务处理失败，可查看日志进行补偿，跟支付宝已经没多大关系。
                return "success";
            } else {
                log.info("支付宝回调签名认证失败，signVerified=false, paramsJson:{}"+paramsJson);
                return "failure";
            }
        } catch (AlipayApiException e) {
            logger.info("支付宝回调签名认证失败,paramsJson:{},errorMsg:{}", paramsJson, e.getMessage());

            return "failure";
        }
    }

    /**
     * 其他支付回调
     */
    @PostMapping("/othernotify")
    @Transactional(rollbackFor = Exception.class)
    public String otherNotify(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException {
        Map<String, String> params = convertRequestParamsToMap(request); // 将异步通知中收到的待验证所有参数都存放到map中
        String paramsJson = JSON.toJSONString(params);
        log.info("其他支付回调，{}"+ paramsJson);
        try {
            String appkey = params.get("appkey");
            if (StringUtils.isEmpty(appkey)||!appkey.equals("eecccca714eaf4659d756eba2d8f034b")) {
                return "支付商户错误";
            }
            String out_trade_no = params.get("out_trade_no");
            AlipayRechargeOrder alipayRechargeOrder = new AlipayRechargeOrder();
            alipayRechargeOrder.setOrderNo(out_trade_no);
            List<AlipayRechargeOrder> alipayRechargeOrders = alipayRechargeOrderService.selectAlipayRechargeOrderList(alipayRechargeOrder);
            if (alipayRechargeOrders.size()==0){
                log.info("支付订单不存在{}"+params.get("out_trade_no"));
                return "支付订单不存在";
            }
            alipayRechargeOrder = alipayRechargeOrders.get(0);
            if (alipayRechargeOrder.getStatus().equals("1")){
                log.info("支付订单已经处理{}"+params.get("out_trade_no"));
                return "支付订单已经处理";
            }
          if (!Objects.equals(Double.parseDouble(String.valueOf(alipayRechargeOrder.getAmount().multiply(new BigDecimal(100)))), Double.parseDouble(params.get("total")))){
              log.info("支付订单金额不一致{}"+params.get("total"));
              return "支付订单金额不一致";
          }

            SysUser sysUser = sysUserService.selectUserById(alipayRechargeOrder.getUserId());

             sysUser.setBalance(sysUser.getBalance().add(alipayRechargeOrder.getAmount()));
             sysUserService.updateUser(sysUser);

            alipayRechargeOrder.setStatus("1");
            alipayRechargeOrder.setFinishTime(new Date());
            alipayRechargeOrderService.updateAlipayRechargeOrder(alipayRechargeOrder);
            return  "SUCCESS";
        }catch (Exception e){
            return "其他支付回调异常:"+e;
        }

    }
    /**
     * 新增藏品订单
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "SysCollectionOrder", name = "sysCollectionOrder", value = ""),
            @ApiImplicitParam(paramType = "query", dataType = "int", name = "payType", value = "")
    })
    @ApiOperation(value = "新增藏品订单", notes = "新增藏品订单", httpMethod = "POST")
    @Log(title = "藏品订单", businessType = BusinessType.INSERT)
    @PostMapping
    @Transactional
    public Result add(@RequestBody SysCollectionOrder sysCollectionOrder,int payType , @RequestHeader(value = "platform",required = false) String platform) throws Exception {
        if (platform==null||platform.equals("")){
            return Result.success();
        }


           SysUser ss = sysUserService.selectUserById(sysCollectionOrder.getUserId());
           if(ss.getRealName() == null || ss.getRealName().equals("")||ss.getIdCard() == null || ss.getIdCard().equals("")){
               return Result.error("请先完善个人实名信息");
           }

           //加锁
           long time = System.currentTimeMillis() + 1000*5;  //超时时间：10秒，最好设为常量

           boolean isLock = redisLock.lock(String.valueOf(sysCollectionOrder.getCollectionShowId()), String.valueOf(time));
           if(!isLock){
               throw new RuntimeException("人太多了，换个姿势再试试~");
           }
           SysCollectionShow sysCollectionShow = sysCollectionShowService.selectSysCollectionShowByCollectionShowIdAndIsSell(sysCollectionOrder.getCollectionShowId());
           if (sysCollectionShow == null) {
               //解锁
               redisLock.unlock(String.valueOf(sysCollectionOrder.getCollectionShowId()),String.valueOf(time));
               return Result.error("藏品已售完");
           }
           if (sysCollectionShow.getCollectionTime() >new Date().getTime()&&ss.getPriorityPurchaseId()==0) {
               //解锁
               redisLock.unlock(String.valueOf(sysCollectionOrder.getCollectionShowId()),String.valueOf(time));
               return Result.error("藏品未开始发售");
           }
           if(sysCollectionShow.getSysCollectionList().size()==0){
               //解锁
               redisLock.unlock(String.valueOf(sysCollectionOrder.getCollectionShowId()),String.valueOf(time));
               return Result.error("藏品已售完");
           }
           //判断是否是优先购买 和到没到时间
            // 可以购买的时间 < 当前时间
        //12.30  < 12  ||  优先购>0
           if (sysCollectionShow.getCollectionTime() < new Date().getTime()||ss.getPriorityPurchaseId()>0)  {

//                //判断优先购买是否到时间
                  // 可以 购买的时间getCollectionTime
                    //现在的时间new Date().getTime()

               if (sysCollectionShow.getCollectionTime()>new Date().getTime()
                       &&ss.getPriorityPurchaseId()>0
                       &&   sysCollectionShow.getCollectionTime()-new Date().getTime() > 30*60*1000

                       &&sysCollectionOrder.getUserId()!=100L&&sysCollectionOrder.getUserId()!=157L) {
//解锁
                   redisLock.unlock(String.valueOf(sysCollectionOrder.getCollectionShowId()),String.valueOf(time));
                   return Result.error("优先购提前半小时可以购买");
               }

               //判断是否拥有两个对应藏品


               SysCollection sysCollection1  = new SysCollection();
                sysCollection1.setCollectionShowId(sysCollectionOrder.getCollectionShowId());
                sysCollection1.setUserId(sysCollectionOrder.getUserId());

               List<SysCollection> sysCollections = sysCollectionService.selectSysCollectionList(sysCollection1);
               if (ss.getIntegral()==0){
                   ss.setIntegral(8888L);
               }
               //订单数量  2 >=2
                if (sysCollections.size()>=ss.getIntegral()&&sysCollectionOrder.getUserId()!=100L&&sysCollectionOrder.getUserId()!=157L) {
                    redisLock.unlock(String.valueOf(sysCollectionOrder.getCollectionShowId()),String.valueOf(time));
                     return Result.error("每个用户只能购买两个藏品");
                }
               //查找 sysCollectionShow.getSysCollectionList()数组中is_sell ="1"的对象并返回 如果没有则抛出异常
               SysCollection sysCollection = sysCollectionShow.getSysCollectionList().get(0);
               System.out.println("余额支付");
               SysUser sysUser = sysUserService.selectUserById(sysCollectionOrder.getUserId());
               if (sysUser.getBalance().compareTo(sysCollection.getCollectionPrice())<0) {
                   //解锁
                   redisLock.unlock(String.valueOf(sysCollectionOrder.getCollectionShowId()),String.valueOf(time));
                   return Result.error("余额不足");
               }


               sysCollection.setIsSell("1");


               sysCollectionOrder.setCollectionId(sysCollection.getCollectionId());
               sysCollectionOrder.setCollectionName(sysCollection.getCollectionName());
               sysCollectionOrder.setCollectionPrice(sysCollection.getCollectionPrice());
               sysCollectionOrder.setOrderPrice(sysCollection.getCollectionPrice());
               sysCollectionOrder.setCollectionHashId(sysCollection.getCollectionHashId());
               sysCollectionOrder.setCollectionShowId(sysCollection.getCollectionShowId());
               sysCollectionOrder.setCollectionUrl(sysCollection.getCollectionUrl());
               sysCollectionOrder.setCollectionAuthorId(sysCollection.getCollectionAuthorId());
               sysCollectionOrder.setCollectionDesc(sysCollection.getCollectionDesc());
               //获取当前时间 yyyy-MM-dd HH:mm:ss格式
               sysCollectionOrder.setCreateTime(new Date());
               sysCollectionOrder.setExpireTime(new Date().getTime() + (1000 * 60 * 5));
               sysCollectionOrder.setOrderStatus("0");
               //生成订单编号 年月日时分秒+随机数 例如：2018070810101010101 共20位 前面10位为时间，后面10位为随机数
               String orderId = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + (int) (Math.random() * 100000000);
               sysCollectionOrder.setCollectionOrderNo(orderId);
               String s = UUID.randomUUID().toString(true);
               sysCollectionOrder.setCollectionOrderNoHashId("0x"+s);
               sysCollectionOrder.setUserId(sysCollectionOrder.getUserId());
               // TODO: 2022/6/2 待完成
               /**
                * 记录原用户ID  和要转给的用户ID  如果交易成功  改变sys_collection 拥有者id  失败不操作
                * */
               sysCollectionService.updateSysCollection(sysCollection);
//               redisCache.setCacheObject("OrderNo"+orderId,sysCollectionOrder,5, TimeUnit.MINUTES);
               sysCollectionOrderService.insertSysCollectionOrder(sysCollectionOrder);

               /**
                * 余额支付
                */

                       try {
//                           redisCache.deleteObject("OrderNo" + orderId);

                           //减少用户余额
                           sysUser.setBalance(sysUser.getBalance().subtract(sysCollection.getCollectionPrice()));
                           //修改用户信息
                           sysUserService.updateUser(sysUser);
                           //设置订单状态
                           sysCollectionOrder.setOrderStatus("1");

                           sysCollectionOrder.setFinishTime(new Date().getTime());

                           //修改订单表
                           sysCollectionOrder.setCollectionOrderId(sysCollectionOrder.getCollectionOrderId());
                           sysCollectionOrderService.updateSysCollectionOrder(sysCollectionOrder);


                           SysCollectionOrder sysCollectionOrdere = new SysCollectionOrder();
                           sysCollectionOrdere.setCollectionOrderNo(orderId);
                           //查询订单 修改订单状态


                           List<SysCollectionOrder> sysCollectionOrders = sysCollectionOrderService.selectSysCollectionOrderList(sysCollectionOrdere);
                           SysCollectionOrder collectionOrder = sysCollectionOrders.get(0);

                           SysCollectionOrderRecord sysCollectionOrderRecord = new SysCollectionOrderRecord();
                           sysCollectionOrderRecord.setCollectionOrderNo(orderId);
                           sysCollectionOrderRecord.setCollectionOrderId(collectionOrder.getCollectionOrderId());
                           sysCollectionOrderRecord.setCollectionDesc(collectionOrder.getCollectionDesc());
                           sysCollectionOrderRecord.setCollectionAuthorId(collectionOrder.getCollectionAuthorId());
                           sysCollectionOrderRecord.setCollectionUrl(collectionOrder.getCollectionUrl());
                           sysCollectionOrderRecord.setCollectionPrice(collectionOrder.getCollectionPrice());
                           sysCollectionOrderRecord.setCollectionOrderNoHashId(collectionOrder.getCollectionOrderNoHashId());
                           sysCollectionOrderRecord.setCollectionHashId(collectionOrder.getCollectionHashId());
                           sysCollectionOrderRecord.setCollectionName(collectionOrder.getCollectionName());
                           sysCollectionOrderRecord.setCollectionId(collectionOrder.getCollectionId());
                           sysCollectionOrderRecord.setFinishTime(collectionOrder.getFinishTime());
                           sysCollectionOrderRecord.setCreateTime(collectionOrder.getCreateTime());
                           sysCollectionOrderRecord.setOldUserId(sysCollection.getUserId());
                           SysUser sysUser3 = sysUserService.selectUserById(sysCollection.getUserId());
                           sysCollectionOrderRecord.setOldUserHashId(sysUser3.getHashId());
                           sysCollectionOrderRecord.setUserId(collectionOrder.getUserId());
                           SysUser sysUser2 = sysUserService.selectUserById(collectionOrder.getUserId());
                           sysCollectionOrderRecord.setUserHashId(sysUser2.getHashId());
                           sysCollectionOrderRecord.setOrderPrice(collectionOrder.getOrderPrice());

                           sysCollectionOrderRecordService.insertSysCollectionOrderRecord(sysCollectionOrderRecord);
                           //修改订单用户
                           sysCollection.setUserId(sysCollectionOrder.getUserId());
                           //添加id
                           sysCollection.setCollectionOrderNoHashId(sysCollectionOrder.getCollectionOrderNoHashId());
                           //添加时间
                           sysCollection.setColletionTime(new Date().getTime());
                           //修改详情表
                           sysCollectionService.updateSysCollection(sysCollection);

                       } catch (Exception e) {
                           //解锁
                           redisLock.unlock(String.valueOf(sysCollectionOrder.getCollectionShowId()),String.valueOf(time));
                           log.info("失败 {}" + e.getMessage());
                           return Result.error("余额支付失败");
                       }
                        if (sysUser.getPriorityPurchaseId() - 1<= 0) {
                            sysUser.setPriorityPurchaseId(0);
                        } else {
                            sysUser.setPriorityPurchaseId(sysUser.getPriorityPurchaseId() - 1);
                        }

                       sysUserService.updateUser(sysUser);

                   //解锁
                   redisLock.unlock(String.valueOf(sysCollectionOrder.getCollectionShowId()),String.valueOf(time));
                   return Result.success("购买成功");



           }

//解锁
        redisLock.unlock(String.valueOf(sysCollectionOrder.getCollectionShowId()),String.valueOf(time));
        return Result.success();

    }

    /**
     * 修改藏品订单
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", dataType = "SysCollectionOrder", name = "sysCollectionOrder", value = "")
    })
    @ApiOperation(value = "修改藏品订单", notes = "修改藏品订单", httpMethod = "PUT")
    @PreAuthorize("@ss.hasPermi('order:order:edit')")
    @Log(title = "藏品订单", businessType = BusinessType.UPDATE)
    @PutMapping
    public Result edit(@RequestBody SysCollectionOrder sysCollectionOrder)
    {
        return toAjax(sysCollectionOrderService.updateSysCollectionOrder(sysCollectionOrder));
    }

    /**
     * 删除藏品订单
     */
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", dataType = "Long[]", name = "collectionOrderIds", value = "")
    })
    @ApiOperation(value = "删除藏品订单", notes = "删除藏品订单", httpMethod = "DELETE")
    @PreAuthorize("@ss.hasPermi('order:order:remove')")
    @Log(title = "藏品订单", businessType = BusinessType.DELETE)
	@DeleteMapping("/{collectionOrderIds}")
    public Result remove(@PathVariable Long[] collectionOrderIds)
    {
        return toAjax(sysCollectionOrderService.deleteSysCollectionOrderByCollectionOrderIds(collectionOrderIds));
    }




    /**
     * 微信支付POST请求
     *
     * @param reqUrl       请求地址 示例：https://api.mch.weixin.qq.com/v3/pay/transactions/app
     * @param paramJsonStr 请求体 json字符串 此参数与微信官方文档一致
     * @return 订单支付的参数
     * @throws Exception
     */

    public static String V3PayPost(String reqUrl, String paramJsonStr) throws Exception {
        //创建post方式请求对象
        HttpPost httpPost = new HttpPost(reqUrl);
        //装填参数
        StringEntity s = new StringEntity(paramJsonStr, "utf-8");
        s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
                "application/json"));
        //设置参数到请求对象中
        httpPost.setEntity(s);
        //指定报文头【Content-type】、【User-Agent】
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type","application/json; charset=utf-8");
        httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
        log.info("请求参数:"+paramJsonStr);
        //执行请求操作，并拿到结果（同步阻塞）
        CloseableHttpResponse response = WxPayHttpClientFactory.httpClient.execute(httpPost);
        int statusCode = response.getStatusLine().getStatusCode();
        //获取数据，并释放资源
        String body = closeHttpResponse(response);
        if (statusCode == 200) { //处理成功
            switch (reqUrl) {
                case "https://api.mch.weixin.qq.com/v3/pay/transactions/app"://返回APP支付所需的参数
                case "https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi":
                    return JSONObject.parseObject(body).getString("prepay_id");
                case "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds"://返回APP退款结果
                    return body;
            }
        }
        return null;
    }
    /**
     * 获取数据，并释放资源
     *
     * @param response
     * @return
     * @throws IOException
     */

    public static String closeHttpResponse(CloseableHttpResponse response) throws IOException {
        String body = "";
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 200) { //处理成功
            //获取结果实体
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                //按指定编码转换结果实体为String类型
                body = EntityUtils.toString(entity, "utf-8");
            }
            //EntityUtils.consume将会释放所有由httpEntity所持有的资源
            EntityUtils.consume(entity);
        }
        //释放链接
        response.close();
        return body;
    }


    /**
     * 微信调起支付参数
     * 返回参数如有不理解 请访问微信官方文档
     * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_2_4.shtml
     *
     * @param prepayId         微信下单返回的prepay_id
     * @param appId            应用ID
     * @param mch_id           商户号
     * @param private_key_path 私钥路径
     * @return 当前调起支付所需的参数
     * @throws Exception
     */

    public static JSONObject WxAppPayTuneUp(String prepayId, String appId, String mch_id, String private_key_path,Boolean flag) throws Exception {
        if (flag){
            if (StringUtils.isNotBlank(prepayId)) {
                long timestamp = System.currentTimeMillis() / 1000;
                String nonceStr = generateNonceStr();
                //加载签名
                String packageSign = sign(buildMessage(appId, timestamp, nonceStr, "prepay_id="+prepayId).getBytes(), private_key_path);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("appId", appId);
                jsonObject.put("timeStamp", timestamp);
                jsonObject.put("nonceStr", nonceStr);

                jsonObject.put("signType", "RSA");
                jsonObject.put("package", "prepay_id=" + prepayId);
                jsonObject.put("signType", "RSA");
                jsonObject.put("paySign", packageSign);

                return jsonObject;
            }
        }else {
            if (StringUtils.isNotBlank(prepayId)) {
                long timestamp = System.currentTimeMillis() / 1000;
                String nonceStr = generateNonceStr();
                //加载签名
                String packageSign = sign(buildMessage(appId, timestamp, nonceStr, prepayId).getBytes(), private_key_path);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("appId", appId);
                jsonObject.put("prepayId", prepayId);
                jsonObject.put("timeStamp", timestamp);
                jsonObject.put("nonceStr", nonceStr);
                jsonObject.put("package", "Sign=WXPay");
                jsonObject.put("signType", "RSA");
                jsonObject.put("sign", packageSign);
                jsonObject.put("partnerId", mch_id);
                return jsonObject;
            }
        }

        return new JSONObject();
    }

    public static String sign(byte[] message, String private_key_path) throws NoSuchAlgorithmException, SignatureException, IOException, InvalidKeyException, InvalidKeyException {
        //签名方式
        Signature sign = Signature.getInstance("SHA256withRSA");
        //私钥
        sign.initSign(PemUtil
                .loadPrivateKey(new ClassPathResource(private_key_path).getInputStream()));
        sign.update(message);

        return Base64.getEncoder().encodeToString(sign.sign());
    }
    /**
     * 按照前端签名文档规范进行排序，\n是换行
     *
     * @param appId     appId
     * @param timestamp 时间
     * @param nonceStr  随机字符串
     * @param prepay_id prepay_id
     * @return
     */




    public static String buildMessage(String appId, long timestamp, String nonceStr, String prepay_id) {
        return appId + "\n"
                + timestamp + "\n"
                + nonceStr + "\n"
                + prepay_id + "\n";
    }
    protected static final SecureRandom RANDOM = new SecureRandom();
    //生成随机字符串 微信底层的方法，直接copy出来了

    protected static String generateNonceStr() {
        char[] nonceChars = new char[32];
        for (int index = 0; index < nonceChars.length; ++index) {
            nonceChars[index] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".charAt(RANDOM.nextInt("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".length()));
        }
        return new String(nonceChars);
    }

    /**
     * 微信支付回调
     * @param request
     * @return
     */

    @PostMapping("/wxAppPayNotify/")
    public JSONObject wxAppPayNotify(HttpServletRequest request, HttpServletResponse response) throws IOException, GeneralSecurityException {
        //从请求头获取验签字段
        String signature = request.getHeader("Wechatpay-Signature");
        String serial = request.getHeader("Wechatpay-Serial");
        ServletInputStream inputStream = request.getInputStream();
        StringBuilder sb = new StringBuilder();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s;
        //读取回调请求体
        while ((s = bufferedReader.readLine()) != null) {
            sb.append(s);
        }
        String s1 = sb.toString();
        //按照文档要求拼接验签串
        String verifySignature = request.getHeader("Wechatpay-Timestamp") + "\n"
                + request.getHeader("Wechatpay-Nonce") + "\n" + s1 + "\n";

        //使用官方验签工具进行验签
        boolean verify1 = WxPayHttpClientFactory.verifier.verify(serial, verifySignature.getBytes(), signature);
        //判断验签的结果
        if (!verify1) {
            //验签失败，应答接口
            //设置状态码
            response.setStatus(500);
            JSONObject jsonResponse = new JSONObject();
            jsonResponse.put("code", "FAIL");
            jsonResponse.put("message", "失败");
            return jsonResponse;
        }

        JSONObject parseObject = JSONObject.parseObject(s1);
        if ("TRANSACTION.SUCCESS".equals(parseObject.getString("event_type"))
                && "encrypt-resource".equals(parseObject.getString("resource_type"))) {
            //通知的类型，支付成功通知的类型为TRANSACTION.SUCCESS
            //通知的资源数据类型，支付成功通知为encrypt-resource
            JSONObject resourceJson = JSONObject.parseObject(parseObject.getString("resource"));
            String associated_data = resourceJson.getString("associated_data");
            String nonce = resourceJson.getString("nonce");
            String ciphertext = resourceJson.getString("ciphertext");
          //  v1JUQpfoAUwnBLI2c27cQBS3TZ1nYgx4
            //解密，如果这里报错，就一定是APIv3密钥错误
            AesUtil aesUtil = new AesUtil("v1JUQpfoAUwnBLI2c27cQBS3TZ1nYgx4".getBytes());
            String aes = aesUtil.decryptToString(associated_data.getBytes(), nonce.getBytes(), ciphertext);
            System.out.println("解密后=" + aes);

            log.info("解密后:{}" ,aes);
            //string转json
            JSONObject jsonObject = JSONObject.parseObject(aes);
            //获取订单号
            String outTradeNo = jsonObject.getString("out_trade_no");

            //获取支付状态
            String tradeState = jsonObject.getString("trade_state");
            //获取支付金额
            String tradeStateDesc = jsonObject.getString("trade_state_desc");
            //获取支付金额
            String amount = jsonObject.getString("amount");
            //获取支付金额
            JSONObject jsonObjects = JSONObject.parseObject(amount);
            String total = jsonObjects.getString("total");

            if (tradeState.equals("SUCCESS")
                    || tradeStateDesc.equals("支付成功")) {
                // 处理支付成功逻辑
                try {
                    System.out.println("======================l============================");
                    logger.info("订单号:{}", outTradeNo);

                    AlipayRechargeOrder alipayRechargeOrder = new AlipayRechargeOrder();
                    alipayRechargeOrder.setOrderNo(outTradeNo);
                    List<AlipayRechargeOrder> alipayRechargeOrders = alipayRechargeOrderService.selectAlipayRechargeOrderList(alipayRechargeOrder);
                    if (alipayRechargeOrders.size()==0){
                        log.info("支付订单不存在{}"+outTradeNo);

                    }
                    alipayRechargeOrder = alipayRechargeOrders.get(0);
                    if (alipayRechargeOrder.getStatus().equals("1")){
                        log.info("支付订单已经处理{}"+outTradeNo);

                    }
                    if (!Objects.equals(Double.parseDouble(String.valueOf(alipayRechargeOrder.getAmount().multiply(new BigDecimal(100)))), Double.parseDouble(total))){
                        log.info("支付订单金额不一致{}"+tradeStateDesc);

                    }

                    SysUser sysUser = sysUserService.selectUserById(alipayRechargeOrder.getUserId());

                    sysUser.setBalance(sysUser.getBalance().add(alipayRechargeOrder.getAmount()));
                    sysUserService.updateUser(sysUser);

                    alipayRechargeOrder.setStatus("1");
                    alipayRechargeOrder.setFinishTime(new Date());
                    alipayRechargeOrderService.updateAlipayRechargeOrder(alipayRechargeOrder);
                } catch (Exception e) {
                    logger.error("微信回调业务处理报错,params:" + aes, e);
                }
            } else {
                logger.error("没有处理微信回调业务，微信交易状态：{},params:{}",tradeState,aes);
            }


            //dosomething 处理业务
        }
        JSONObject jsonResponse = new JSONObject();
        jsonResponse.put("code", "SUCCESS");
        jsonResponse.put("message", "成功");
        //设置状态码
        response.setStatus(200);
        return jsonResponse;
     }






    private ExecutorService executorService = Executors.newFixedThreadPool(20);

    /**
     * <pre>
     * 第一步:验证签名,签名通过后进行第二步
     * 第二步:按一下步骤进行验证
     * 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
     * 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额），
     * 3、校验通知中的seller_id（或者seller_email) 是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email），
     * 4、验证app_id是否为该商户本身。上述1、2、3、4有任何一个验证不通过，则表明本次通知是异常通知，务必忽略。
     * 在上述验证通过后商户必须根据支付宝不同类型的业务通知，正确的进行不同的业务处理，并且过滤重复的通知结果数据。
     * 在支付宝的业务通知中，只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时，支付宝才会认定为买家付款成功。
     * </pre>
     *
     * @param request
     * @return
     */

    @PostMapping("/alinotify")
    @ResponseBody
    public String callback(HttpServletRequest request) {
        Map<String, String> params = convertRequestParamsToMap(request); // 将异步通知中收到的待验证所有参数都存放到map中
        String paramsJson = JSON.toJSONString(params);
      log.info("支付宝回调，{}"+ paramsJson);
        try {
            AlipayConfig alipayConfig = new AlipayConfig();// 支付宝配置
            // 调用SDK验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(params, ymlParament.getAlipayPublickey(), ymlParament.getCharset(),
                    ymlParament.getSignType());
            if (signVerified) {
                log.info("支付宝回调签名认证成功");
                // 按照支付结果异步通知中的描述，对支付结果中的业务内容进行1\2\3\4二次校验，校验成功后在response中返回success，校验失败返回failure
                this.check(params);
                // 另起线程处理业务
                executorService.execute(new Runnable() {
                    @Override
                    public void run() {
                        AlipayNotifyParam param = buildAlipayNotifyParam(params);
                        String trade_status = param.getTradeStatus();
                        // 支付成功
                        if (trade_status.equals("TRADE_SUCCESS")
                                || trade_status.equals("TRADE_FINISHED")) {
                            // 处理支付成功逻辑
                            try {
                                System.out.println("======================l============================");
                                logger.info(params.get("out_trade_no"));

                                String outTradeNo = params.get("out_trade_no");
                                logger.info("out_trade_no，{}", outTradeNo);
                                // 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
                                SysCollectionOrder sysCollectionOrder = new SysCollectionOrder();
                                sysCollectionOrder.setCollectionOrderNo(outTradeNo);
                                //查询订单 修改订单状态
                                List<SysCollectionOrder> sysCollectionOrders = sysCollectionOrderService.selectSysCollectionOrderList(sysCollectionOrder);
                                if (sysCollectionOrders.size() == 0) {
                                    // 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
                                    AlipayRechargeOrder alipayRechargeOrder = new AlipayRechargeOrder();
                                    alipayRechargeOrder.setOrderNo(outTradeNo);
                                    List<AlipayRechargeOrder> alipayRechargeOrders = alipayRechargeOrderService.selectAlipayRechargeOrderList(alipayRechargeOrder);
                                    if (alipayRechargeOrders.size()>0) {
                                        alipayRechargeOrder = alipayRechargeOrders.get(0);
                                        alipayRechargeOrder.setStatus("1");
                                        alipayRechargeOrder.setFinishTime(new Date());
                                        alipayRechargeOrderService.updateAlipayRechargeOrder(alipayRechargeOrder);

                                        SysUser sysUser = sysUserService.selectUserById(alipayRechargeOrder.getUserId());
                                        sysUser.setBalance(sysUser.getBalance().add(alipayRechargeOrder.getAmount()));
                                        sysUserService.updateUser(sysUser);

                                    }
                                }
                                SysCollectionOrder collectionOrder = sysCollectionOrders.get(0);
                                sysCollectionService.selectSysCollectionByCollectionId(collectionOrder.getCollectionId());


                                collectionOrder.setOrderStatus("1");
                                collectionOrder.setFinishTime(new Date().getTime());
                               sysCollectionOrderService.updateSysCollectionOrder(collectionOrder);
                                SysCollection sysCollection = sysCollectionService.selectSysCollectionByCollectionId(collectionOrder.getCollectionId());
                                //记录业务日志



                                SysCollectionOrderRecord sysCollectionOrderRecord = new SysCollectionOrderRecord();
                                sysCollectionOrderRecord.setCollectionOrderNo(outTradeNo);
                                sysCollectionOrderRecord.setCollectionOrderId(collectionOrder.getCollectionOrderId());
                                sysCollectionOrderRecord.setCollectionDesc(collectionOrder.getCollectionDesc());
                                sysCollectionOrderRecord.setCollectionAuthorId(collectionOrder.getCollectionAuthorId());
                                sysCollectionOrderRecord.setCollectionUrl(collectionOrder.getCollectionUrl());
                                sysCollectionOrderRecord.setCollectionPrice(collectionOrder.getCollectionPrice());
                                sysCollectionOrderRecord.setCollectionOrderNoHashId(collectionOrder.getCollectionOrderNoHashId());
                                sysCollectionOrderRecord.setCollectionHashId(collectionOrder.getCollectionHashId());
                                sysCollectionOrderRecord.setCollectionName(collectionOrder.getCollectionName());
                                sysCollectionOrderRecord.setCollectionId(collectionOrder.getCollectionId());
                               sysCollectionOrderRecord.setFinishTime(collectionOrder.getFinishTime());
                               sysCollectionOrderRecord.setOldUserId(sysCollection.getUserId());
                                sysCollectionOrderRecord.setCreateTime(collectionOrder.getCreateTime());
                                SysUser sysUser = sysUserService.selectUserById(sysCollection.getUserId());
                                sysCollectionOrderRecord.setOldUserHashId(sysUser.getHashId());
                                sysCollectionOrderRecord.setUserId(collectionOrder.getUserId());
                                SysUser sysUser2 = sysUserService.selectUserById(collectionOrder.getUserId());
                                sysCollectionOrderRecord.setUserHashId(sysUser2.getHashId());

                                sysCollectionOrderRecord.setOrderPrice(collectionOrder.getOrderPrice());
                                sysCollectionOrderRecordService.insertSysCollectionOrderRecord(sysCollectionOrderRecord);

                               //修改持有者id

                                sysCollection.setUserId(collectionOrder.getUserId());
                                sysCollection.setCollectionOrderNoHashId(collectionOrder.getCollectionOrderNoHashId());
                                sysCollection.setColletionTime(collectionOrder.getFinishTime());
                                sysCollection.setCollectionId(collectionOrder.getCollectionId());
                                sysCollectionService.updateSysCollection(sysCollection);
                                redisCache.deleteObject("OrderNo"+outTradeNo);
                            } catch (Exception e) {
                                logger.error("支付宝回调业务处理报错,params:" + paramsJson, e);
                            }
                        } else {
                            logger.error("没有处理支付宝回调业务，支付宝交易状态：{},params:{}",trade_status,paramsJson);
                        }
                    }
                });
                // 如果签名验证正确，立即返回success，后续业务另起线程单独处理
                // 业务处理失败，可查看日志进行补偿，跟支付宝已经没多大关系。
                return "success";
            } else {
                log.info("支付宝回调签名认证失败，signVerified=false, paramsJson:{}"+paramsJson);
                return "failure";
            }
        } catch (AlipayApiException e) {
            logger.info("支付宝回调签名认证失败,paramsJson:{},errorMsg:{}", paramsJson, e.getMessage());

            return "failure";
        }
    }

    // 将request中的参数转换成Map

    private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> retMap = new HashMap<String, String>();

        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();

        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int valLen = values.length;

            if (valLen == 1) {
                retMap.put(name, values[0]);
            } else if (valLen > 1) {
                StringBuilder sb = new StringBuilder();
                for (String val : values) {
                    sb.append(",").append(val);
                }
                retMap.put(name, sb.toString().substring(1));
            } else {
                retMap.put(name, "");
            }
        }

        return retMap;
    }


    private AlipayNotifyParam buildAlipayNotifyParam(Map<String, String> params) {
        String json = JSON.toJSONString(params);
        return JSON.parseObject(json, AlipayNotifyParam.class);
    }

    /**
     * 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
     * 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额），
     * 3、校验通知中的seller_id（或者seller_email)是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email），
     * 4、验证app_id是否为该商户本身。上述1、2、3、4有任何一个验证不通过，则表明本次通知是异常通知，务必忽略。
     * 在上述验证通过后商户必须根据支付宝不同类型的业务通知，正确的进行不同的业务处理，并且过滤重复的通知结果数据。
     * 在支付宝的业务通知中，只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时，支付宝才会认定为买家付款成功。
     *
     * @param params
     * @throws AlipayApiException
     */

    private void check(Map<String, String> params) throws AlipayApiException {
        String outTradeNo = params.get("out_trade_no");
        logger.info("out_trade_no，{}", outTradeNo);
        // 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号，
        SysCollectionOrder sysCollectionOrder = new SysCollectionOrder();
        sysCollectionOrder.setCollectionOrderNo(outTradeNo);

        List<SysCollectionOrder> sysCollectionOrders = sysCollectionOrderService.selectSysCollectionOrderList(sysCollectionOrder);
        AlipayRechargeOrder alipayRechargeOrder = new AlipayRechargeOrder();
        alipayRechargeOrder.setOrderNo(outTradeNo);
        List<AlipayRechargeOrder> alipayRechargeOrders = alipayRechargeOrderService.selectAlipayRechargeOrderList(alipayRechargeOrder);

        if (sysCollectionOrders != null && sysCollectionOrders.size() != 0) {
            SysCollectionOrder sysCollectionOrder1 = sysCollectionOrders.get(0);

            double v = sysCollectionOrder1.getCollectionPrice().doubleValue();
            if (v != Double.parseDouble(params.get("total_amount")) ) {
                throw new AlipayApiException("订单金额不符");
            }
        }else if (alipayRechargeOrders != null && alipayRechargeOrders.size() != 0) {
            AlipayRechargeOrder alipayRechargeOrder1 = alipayRechargeOrders.get(0);
            if ( alipayRechargeOrder1.getAmount().doubleValue() != Double.parseDouble(params.get("total_amount"))){
                throw new AlipayApiException("订单金额不符");
            }
        }else {
            throw new AlipayApiException("订单不存在");
        }
        // 2、判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额），


        // 3、校验通知中的seller_id（或者seller_email)是否为out_trade_no这笔单据的对应的操作方（有的时候，一个商户可能有多个seller_id/seller_email），
        // 第三步可根据实际情况省略

        // 4、验证app_id是否为该商户本身。
        if (!params.get("app_id").equals(ymlParament.getAppId())) {
            throw new AlipayApiException("app_id不一致");
        }
    }


    @ApiOperation("ios支付成功后验证结果")
    @RequestMapping(value = "/iPayNotify", method = RequestMethod.POST)
    @ResponseBody
    public Result iPayNotify(@RequestBody IPayNotifyPo iPayNotifyPo) {

        log.debug("前段传递的ios支付参数=" + iPayNotifyPo.toString());

        String receipt = iPayNotifyPo.getTransactionReceipt();

        // 拿到收据的MD5
        String receiptMd5 = SecureUtil.md5(receipt);
        // 查询数据库，看是否是己经验证过的该支付收据

        // 1.先线上测试    发送平台验证
        String verifyResult = IosVerifyUtil.buyAppVerify(receipt, 1);
        log.debug("1，苹果返回的参数=" + verifyResult);
        if (verifyResult == null) {
            // 苹果服务器没有返回验证结果
            log.debug("苹果服务器没有返回验证结果");
            return Result.error("订单没有找到");
        } else {
            // 苹果验证有返回结果
            cn.hutool.json.JSONObject job = JSONUtil.parseObj(verifyResult);
            log.debug("2，苹果验证返回的json串=" + job.toString());
            String states = job.getStr("status");

            if ("21007".equals(states)) {

                log.debug("是沙盒环境，应沙盒测试，否则执行下面");

                // 是沙盒环境，应沙盒测试，否则执行下面
                // 2.再沙盒测试  发送平台验证
                verifyResult = IosVerifyUtil.buyAppVerify(receipt, 0);
                job = JSONUtil.parseObj(verifyResult);
                log.debug("3，沙盒环境验证返回的json字符串=" + job.toString());
                states = job.getStr("status");
                return  Result.error("当前是测试环境");
            }
            if ("0".equals(states)) { // 前端所提供的收据是有效的    验证成功

                log.debug("前端所提供的收据是有效的    验证成功");

                String r_receipt = job.getStr("receipt");
                cn.hutool.json.JSONObject returnJson = JSONUtil.parseObj(r_receipt);
                String in_app = returnJson.getStr("in_app");

                /**
                 * in_app说明：
                 * 验证票据返回的receipt里面的in_app字段，这个字段包含了所有你未完成交易的票据信息。也就是在上面说到的APP完成交易之后，这个票据信息，就会从in_app中消失。
                 * 如果APP不完成交易，这个票据信息就会在in_app中一直保留。(这个情况可能仅限于你的商品类型为消耗型)
                 *
                 * 知道了事件的原委，就很好优化解决了，方案有2个
                 * 1.对票据返回的in_app数据全部进行处理，没有充值的全部进行充值
                 * 2.仅对最新的充值信息进行处理（我们采取的方案）
                 *
                 * 因为采用一方案：
                 * 如果用户仅进行了一次充值，该充值未到账，他不再进行充值了，那么会无法导致。
                 * 如果他通过客服的途径已经进行了补充充值，那么他在下一次充值的时候依旧会把之前的产品票据带回，这时候有可能出现重复充值的情况
                 *
                 * 以上说明是我在网上找到的，可以查看原文
                 * https://www.cnblogs.com/widgetbox/p/8241333.html
                 */

                JSONArray jsonArray = JSONUtil.parseArray(in_app);
                if (jsonArray.size() > 0) {
                    int index = 0;
                    cn.hutool.json.JSONObject o = JSONUtil.parseObj(jsonArray.get(index));
                    log.info("4，苹果验证返回的in_app字符串=" + o.toString());
                    String transaction_id = o.getStr("transaction_id"); // 订单号
                    String product_id = o.getStr("product_id"); // 产品id，也就是支付金额
                    String purchase_date_ms = o.getStr("purchase_date_ms"); // 支付时间

                    // 添加支付金额
                    SysUser sysUser =  sysUserService.selectUserById(iPayNotifyPo.getUserId());
                    sysUser.setUserId(iPayNotifyPo.getUserId());
                    sysUser.setBalance(sysUser.getBalance().add(new BigDecimal(product_id)));
                    sysUserService.updateUser(sysUser);

                }
            } else {
                return Result.error("收到数据有误");
            }
        }
        return Result.success("充值成功");
    }



}







